﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using VnSegmenter.Core;

using cit.CopyDetection.DataObject;
using cit.CopyDetection.DatabaseAccess;

namespace cit.CopyDetection.Preprocessing
{
    /// <summary>
    /// Phân tích các văn bảng thành các token
    /// </summary>
    public class TextSegmenter
    {
        //Từ điển dùng cho việc tách từ
        private Dictionary _dict = null;

        //Danh sách các stopword
        private List<string> _stopwords = null;

        /// <summary>
        /// Phân tích văn bản thành các token xác định bởi ký tự
        /// </summary>
        /// <param name="text">Văn bản phân tích</param>
        /// <param name="delimiter">Ký tự dùng để phân tích</param>
        /// <returns>Các token</returns>
        public string[] SegmentText(string text, char delimiter)
        {
            return text.Split(new char[] { delimiter });
        }

        /// <summary>
        /// Phân tích văn bản thành các đoạn văn bản bởi ký tự 'CR'
        /// </summary>
        /// <param name="text">Văn bản phân tích</param>
        /// <returns>Các đoạn văn bản</returns>
        public string[] SegmentTextinParagraphs(string text)
        {
            return SegmentText(text, '\r');
        }

        /// <summary>
        /// Phân tích tập tin văn bản thành các đoạn văn bản bởi ký tự 'CR'
        /// </summary>
        /// <param name="fileName">Địa chỉ tập tin văn bản phân tích</param>
        /// <returns>Các đoạn văn bản</returns>
        public string[] SegmentFileinParagraphs(string fileName)
        {
            StreamReader sReader = new StreamReader(fileName, Encoding.UTF8);
            string[] paragraphs = this.SegmentTextinParagraphs(sReader.ReadToEnd());
            sReader.Close();

            return paragraphs;
        }

        /// <summary>
        /// Phân tích văn bản thành các thuật ngữ
        /// </summary>
        /// <param name="paragraph">Văn bản cần phân tích</param>
        /// <returns>Các thuật ngữ</returns>
        public List<Term> SegmentTextinTerms(string paragraph) 
        {
            if (_dict == null)
                _dict = MMSeg.loadDict();

            if (_stopwords == null)
                _stopwords = TermDataAccess.GetStopwords();

            string[] words = MMSeg.segment(MMSeg.Normalize(paragraph), _dict, Config.THREE_WORD);
            var normalizedWords = words
                .Select(word => word.Trim().ToLower())
                .Where(word => (word.Length > 0) && !IsStopword(word));
            
            if (normalizedWords.Count() < ConfigReader.MinLength) return null;

            List<Term> terms = new List<Term>();
            foreach (string word in normalizedWords)
            {
                int index = terms.FindIndex(term => term.Equals(word));
                if (index == -1)
                {
                    Term term = new Term() { WordString = word, GlobalFrequency = 1 };
                    terms.Add(term);
                }
                else
                {
                    Term term = terms[index];
                    term.GlobalFrequency++;
                    terms[index] = term;
                } 
            }

            return terms;
        }

        /// <summary>
        /// Kiểm tra một từ có nằm trong danh sách stopword 
        /// </summary>
        /// <param name="word">Từ cần kiểm tra</param>
        /// <returns>true nếu từ có trong danh sách stopword, ngược lại trả về false</returns>
        private bool IsStopword(string word)
        {
            return _stopwords.Exists(stopword => string.Equals(stopword, word, StringComparison.InvariantCultureIgnoreCase));
        }
    }
}
